Der Datensatz, der in diesem Projekt analysiert wird, stammt von der website “Kaggle” und beschreibt das Gehalt nach Job und Land in dem gearbeitet wird.
Code
salary <-read_csv("Salary.csv")
Rows: 6684 Columns: 9
── Column specification ────────────────────────────────────────────────────────
Delimiter: ","
chr (4): Gender, Job Title, Country, Race
dbl (5): Age, Education Level, Years of Experience, Salary, Senior
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
Erster Überblick der Daten
Um einen ersten Überblick zu erhalten, werden die ersten 10 Zeilen der Tabelle ausgelesen:
Code
head(salary, 10)
# A tibble: 10 × 9
Age Gender `Education Level` `Job Title` `Years of Experience` Salary
<dbl> <chr> <dbl> <chr> <dbl> <dbl>
1 32 Male 1 Software Engineer 5 90000
2 28 Female 2 Data Analyst 3 65000
3 45 Male 3 Manager 15 150000
4 36 Female 1 Sales Associate 7 60000
5 52 Male 2 Director 20 200000
6 29 Male 1 Marketing Analyst 2 55000
7 42 Female 2 Product Manager 12 120000
8 31 Male 1 Sales Manager 4 80000
9 26 Female 1 Marketing Coordi… 1 45000
10 38 Male 3 Scientist 10 110000
# ℹ 3 more variables: Country <chr>, Race <chr>, Senior <dbl>
Mithilfe der “describe_tbl”- Funktion können die generellen Informationen über den Datensatz ermittelt werden.
Code
describe_tbl(salary)
6 684 (6.7k) observations with 9 variables
0 observations containing missings (NA)
0 variables containing missings (NA)
0 variables with no variance
Wie oben zu erkennen, enthält der Datensatz 6684 Instanzen, wovon keine einen Wert ohne Angabe (NA’s) besitzt.
Nun wird ein kurzer Blick auf die Art der Merkmale geholfen. Gibt es kategorische oder nummerische Merkmale innerhalb des Datensatzes?
Code
describe(salary)
# A tibble: 9 × 8
variable type na na_pct unique min mean max
<chr> <chr> <int> <dbl> <int> <dbl> <dbl> <dbl>
1 Age dbl 0 0 41 21 33.6 62
2 Gender chr 0 0 2 NA NA NA
3 Education Level dbl 0 0 4 0 1.62 3
4 Job Title chr 0 0 129 NA NA NA
5 Years of Experience dbl 0 0 37 0 8.08 34
6 Salary dbl 0 0 437 350 115307. 250000
7 Country chr 0 0 5 NA NA NA
8 Race chr 0 0 10 NA NA NA
9 Senior dbl 0 0 2 0 0.14 1
Wie bereits oben in der Tabelle zu erkennen gibt es Innerhalb des Datensatzes nur zwei verschiedene Datentypen. Die Felder *Age, Education Level, Years of Experience, Salary, Senior* sind nummerische Merkmale. Die Felder Gender, Job Title, Country, Race sind kategorische Merkmale.
Spalte
Typ
Bedeutung
Age
Numerisch
Alter
Gender
Kategorisch
Geschlecht
Education Level
Numerisch
Bildungsgrad
Job Title
Kategorisch
Jobtitel
Years of Experience
Numerisch
Arbeitserfahrung in Jahren
Salary
Numerisch
Gehalt
Country
Kategorisch
Land
Race
Kategorisch
Ethnizität
Senior
Numerisch
Senior position ja(1)/nein(0)
Im folgenden Abschnitt werden verschiedene Funktionen dafür verwendet, um die Datentypen und Bedeutung der Spalten zu verstehen.
Hier werden die Spaltennamen der Spalten verändert, welche ein Leerzeichen im Namen haben. Es handelt sich hierbei um die Spalten “Job Title”, “Years of Experience” und “Education level”. Das Leerzeichen wird einfach durch einen Punkt ersetzt. Da noch häufig im Laufe des Projektes auf die Spaltennamen zugegriffen werdne muss, wird Uns das in der Zukunft noch Zeit sparen.
Nun werfen verschaffen Wir uns einen Überblick über die prozentuale Verteilung der Jobtitel. Aus der Grafik geht hervor, dass der Beruf des “Data Scientist” der meist ausgeführte Beruf ist. Außerdem gibt es innerhalb des Datensatzes auch viele “Data Analsysten” , sowie auch “Backend Devolper”.
Code
explore (salary, Job.Title)
Grundlegende Statistische Merkmale des Datensatzes
Im folgenden wird ein Überblick über die grundlegenden statistischen Merkmale geworfen:
Code
summary(salary)
Age Gender Education.Level Job.Title
Min. :21.00 Length:6684 Min. :0.000 Length:6684
1st Qu.:28.00 Class :character 1st Qu.:1.000 Class :character
Median :32.00 Mode :character Median :1.000 Mode :character
Mean :33.61 Mean :1.622
3rd Qu.:38.00 3rd Qu.:2.000
Max. :62.00 Max. :3.000
Years.Of.Experience Salary Country Race
Min. : 0.000 Min. : 350 Length:6684 Length:6684
1st Qu.: 3.000 1st Qu.: 70000 Class :character Class :character
Median : 7.000 Median :115000 Mode :character Mode :character
Mean : 8.078 Mean :115307
3rd Qu.:12.000 3rd Qu.:160000
Max. :34.000 Max. :250000
Senior
Min. :0.0000
1st Qu.:0.0000
Median :0.0000
Mean :0.1435
3rd Qu.:0.0000
Max. :1.0000
Erkennbar hier ist es, dass es innerhalb des Datensatzes ein durchschnittliches Alter von 32 Jahren vorliegt. Das Alter streckt sich von 21 Jahren bis zu 62 Jahren. Außerdem gibt es beim “Education-Level” Werte zwischen 1, 2 und 3, wobei der Durchschnitt jedoch bei 1 liegt. Außerdem gibt es bei der Berufserfahrung ( Years of Experience) Werte zwischen 0 bis zu 34 Jahren. Der Median hier beträgt 7.
Umstrukturierung des Datensatzes zwecks Visualisierung
Im folgenden wird der Datensatz umstrukturiert und ein neuer Wert Namens “Value” wird erschaffen. Dies geschieht um möglicherweise besser analysieren und visualisieren zu können.
# A tibble: 6 × 2
name value
<chr> <dbl>
1 Age 32
2 Education.Level 1
3 Years.Of.Experience 5
4 Salary 90000
5 Age 28
6 Education.Level 2
Insgesamt werden in diesem Codechunk die Spalten die nicht nummerische Merkmale sind entfernt und der verbleibende Datensatz wird von einem breiten in ein längeres Format umgewandelt.
`stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
Hier kann man folgende Dinge erkennen:
Age, Years of Experience und Education Level sind Linksschief und haben ggf. Bedarf einer Transformation für ML-Modelle
Age und Years of Experience haben Extrempunkte im oberen Wertebereich, während Salary einer gleichmäßigen Verteilung folgt
Aufgrund der guten Strukturiertheit der Daten eignen sie sich dem ersten Anschein nach gut für eine Ausführliche Explorative Analyse.
Kategorisierung von Gehalt
Zunächst werden die Daten aus dem Ausgangsdatensatz in einen finalen Datensatz “salary_final” geschrieben.
Code
salary_final <- salary
Durch den Befehl “hist()” wird ein Histogramm erstellt . Es ermöglicht eine visuelle Darstellung der Häufigkeitsverteilung dieses GEhlatsdaten, indem es zeigt, wie oft bestimmte Gehaltsbereiche vorkommen.
Code
hist(salary_final$Salary)
Im folgenden wird eine neue Spalte “SalaryKat” erstellt die kategorische Werte basdierend auf den Gehältern enthält…
# Korrelation zwischen Salary und Years.Of.Experience berechnencorrelation_salary_experience <-cor(salary_final$Salary, salary_final$Years.Of.Experience)# Ausgabe des Ergebnissescat("Die Korrelation zwischen Salary und Years.Of.Experience ist:", correlation_salary_experience, "\n")
Die Korrelation zwischen Salary und Years.Of.Experience ist: 0.8109416
Code
# Korrelation zwischen Salary und Age berechnencorrelation_salary_age <-cor(salary_final$Salary, salary_final$Age, use ="complete.obs")# Ausgabe des Ergebnissescat("Die Korrelation zwischen Salary und Age ist:", correlation_salary_age, "\n")
Die Korrelation zwischen Salary und Age ist: 0.7283429
Code
# Korrelation zwischen Years.Of.Experience und Age berechnencorrelation_experience_age <-cor(salary_final$Years.Of.Experience, salary_final$Age, use ="complete.obs")# Ausgabe des Ergebnissescat("Die Korrelation zwischen Years.Of.Experience und Age ist:", correlation_experience_age, "\n")
Die Korrelation zwischen Years.Of.Experience und Age ist: 0.9376094
Code
# Korrelation zwischen Seniority und Years.Of.Experience berechnencorrelation_seniority_experience <-cor(salary_final$Senior, salary_final$Years.Of.Experience, use ="complete.obs")# Ausgabe des Ergebnissescat("Die Korrelation zwischen Seniority und Years.Of.Experience ist:", correlation_seniority_experience, "\n")
Die Korrelation zwischen Seniority und Years.Of.Experience ist: 0.3178772
das ergebnis der correlationen: von salary und years.of.experience ist es 0.81 von Salary und Age ist es 0.73 und die von Age und Years.Of.Experience ist 0.93 wie kommt so ein starker unterschied zu stande bei den werten im vergleich zu salary obwohl sie doch eine hohe correlation zueinander haben
Verteilung der Daten: Es ist möglich, dass die Verteilung der Daten in den Variablen “Age” und “Years.Of.Experience” anders ist als in der Variable “Salary”. Wenn die Daten in “Age” und “Years.Of.Experience” breiter gestreut sind, kann dies zu einer geringeren Korrelation führen, selbst wenn eine starke lineare Beziehung besteht.
Nicht-lineare Beziehung: Die Korrelation misst nur lineare Beziehungen. Wenn die Beziehung zwischen “Age” und “Years.Of.Experience” nicht linear ist, könnte dies zu einem niedrigeren Korrelationswert führen.
Ausreißer: Das Vorhandensein von Ausreißern kann die Korrelation beeinflussen. Wenn es Ausreißer in einer der Variablen gibt, kann dies den Korrelationswert beeinträchtigen.
Stichprobengröße: Bei kleineren Stichproben können Korrelationswerte instabiler sein.
Tests für Thesen
im folgenden werden anhand der Daten ein paar Tests durchgeführt um aussagen für Thesen heruaszufiltern. Das Ergebnis dieses Codechunks ist eine Darstellung der Korrelationsmatrix.
Erkennbar hier ist es zum Beispiel eine starke Korrelation zwischen dem Alter und den “Years of Experience”. Desweiteren liegt auch eine starke Korrelation zwischnem den Years of Experience und dem entgültigen Gehalt. Eine nichgt so starke Korrelation liegt zwischen dem Alter und dem Education Level mit einem Wert von ungefähr 0,6.
Code
ggplot(salary_final, aes(x = Years.Of.Experience, y = Salary)) +geom_point(color ="blue", size =3, shape =16) +labs(title ="Scatter Plot of Years of Experience vs Salary",x ="Years of Experience",y ="Salary")
Code
ggplot(salary_final, aes(x = Education.Level, y = Salary)) +geom_point(color ="blue", size =3, shape =16) +labs(title ="Scatter Plot of Years of Experience vs Salary",x ="Years of Experience",y ="Salary")
Code
ggplot(salary_final, aes(x = Race, y = Salary)) +geom_bar(stat ="summary", fun ="mean", fill ="blue") +labs(title ="Average Salary by Race",x ="Race",y ="Average Salary")
Code
ggplot(salary_final, aes(x = Country, y = Salary, fill = Country)) +geom_bar(stat ="summary", fun ="mean", position ="dodge", color ="black") +labs(title ="Average Salary by Country",x ="Country",y ="Average Salary") +theme(axis.text.x =element_text(angle =45, hjust =1))
Code
ggplot(salary_final, aes(x = Country, y = Salary, fill = Gender)) +geom_bar(stat ="summary", fun ="mean", position ="stack", color ="black") +labs(title ="Average Salary by Country and Gender",x ="Country",y ="Average Salary") +theme(axis.text.x =element_text(angle =45, hjust =1))
Code
ggplot(salary_final, aes(x = Country, y = Salary, fill =factor(Education.Level))) +geom_bar(stat ="summary", fun ="mean", position ="dodge", color ="black") +labs(title ="Average Salary by Country and Education Level",x ="Country",y ="Average Salary") +theme(axis.text.x =element_text(angle =45, hjust =1))
Code
ggplot(salary_final, aes(x = Country, y = Salary, fill = Race)) +geom_bar(stat ="summary", fun ="mean", position ="stack", color ="black") +labs(title ="Average Salary by Country and Race",x ="Country",y ="Average Salary") +theme(axis.text.x =element_text(angle =45, hjust =1))
Code
ggplot(salary_final, aes(x = Country, y = Salary, fill = Race)) +geom_boxplot() +stat_summary(fun ="median", geom ="point", shape =18, size =3, color ="red", position =position_dodge(width =0.75)) +labs(title ="Salary Distribution by Country and Race",x ="Country",y ="Salary") +theme(axis.text.x =element_text(angle =45, hjust =1))
Hier wird festgestellt das in dem Datensatz zu viele Jobtitle vorkommen
Code
ggplot(salary_final, aes(x = Job.Title, y = Salary)) +geom_bar(stat ="summary", fun ="mean", fill ="blue", color ="black") +labs(title ="Average Salary by Job Title",x ="Job Title",y ="Average Salary") +theme(axis.text.x =element_text(angle =45, hjust =1))
Account Executive Account Manager
1 4
Accountant Administrative Assistant
6 2
Advertising Coordinator Back end Developer
1 242
Business Analyst Business Development Associate
20 7
Business Development Manager Business Intelligence Analyst
5 1
Business Operations Analyst CEO
2 1
Chief Data Officer Chief Technology Officer
1 1
Consultant Content Marketing Manager
1 73
Copywriter Creative Director
2 1
Customer Service Manager Customer Service Rep
2 1
Customer Service Representative Customer Success Manager
6 1
Customer Success Rep Customer Support Specialist
1 1
Data Analyst Data Engineer
391 4
Data Entry Clerk Data Scientist
1 515
Delivery Driver Designer
5 1
Developer Digital Content Producer
1 1
Digital Marketing Manager Digital Marketing Specialist
52 15
Director Director of Business Development
1 1
Director of Data Science Director of Engineering
57 2
Director of Finance Director of HR
2 69
Director of Human Capital Director of Human Resources
1 2
Director of Marketing Director of Operations
88 11
Director of Product Management Director of Sales
1 1
Director of Sales and Marketing Engineer
1 2
Event Coordinator Financial Advisor
2 5
Financial Analyst Financial Manager
53 139
Front end Developer Front End Developer
239 31
Full Stack Engineer Graphic Designer
304 23
Help Desk Analyst HR Coordinator
1 29
HR Generalist HR Manager
104 5
HR Specialist Human Resources Coordinator
1 50
Human Resources Director Human Resources Manager
1 152
Human Resources Specialist IT Consultant
1 2
IT Manager IT Project Manager
1 1
IT Support IT Support Specialist
1 2
Juniour HR Coordinator Juniour HR Generalist
3 3
Manager Marketing Analyst
2 144
Marketing Coordinator Marketing Director
167 65
Marketing Manager Marketing Specialist
315 10
Network Engineer Office Manager
1 1
Operations Analyst Operations Coordinator
8 5
Operations Director Operations Manager
1 122
Principal Engineer Principal Scientist
1 1
Product Designer Product Development Manager
80 1
Product Manager Product Marketing Manager
323 70
Project Coordinator Project Engineer
5 317
Project Manager Public Relations Manager
34 1
Quality Assurance Analyst Receptionist
1 57
Recruiter Research Director
3 75
Research Scientist Researcher
119 1
Sales Associate Sales Director
212 62
Sales Executive Sales Manager
38 58
Sales Operations Manager Sales Representative
1 81
Scientist Social Media Man
3 1
Social Media Manager Social Media Specialist
15 2
Software Architect Software Developer
1 186
Software Engineer Software Engineer Manager
809 376
Software Manager Software Project Manager
1 1
Strategy Consultant Supply Chain Analyst
1 1
Supply Chain Manager Technical Recruiter
1 1
Technical Support Specialist Technical Writer
1 1
Training Specialist UX Designer
2 5
UX Researcher VP of Finance
1 1
VP of Operations Web Designer
1 1
Web Developer
129
Hier nochmal das obere genauer grafisch herausgearbeitet
Code
job_title_count <-table(salary_final$Job.Title)job_title_df <-data.frame(Job_Title =names(job_title_count), Frequency =as.numeric(job_title_count))ggplot(job_title_df, aes(x = Job_Title, y = Frequency)) +geom_bar(stat ="identity", fill ="blue", color ="black") +labs(title ="Frequency of Unique Job Titles",x ="Job Titles",y ="Frequency") +theme(axis.text.x =element_text(angle =45, hjust =1))
Da in dem Datensatz teilweise Jobs nur einmalig vertreten sind, kann ein erhebliches Stichproben-Bias verursacht werden. Da das mittlere Einkommen ein wichtiges Merkmal in unserer explorativen Datenanalyse darstellt und mindestens 30 Einträge für eine aussagekräftige Stichprobe nötig sind, haben wir uns dazu entschlossen alle Einträge mit N<30 bei der Anzahl der Jobtitel (N) abzuschneiden.
# A tibble: 6,398 × 11
Job.Title job_count Age Gender Education.Level Years.Of.Experience Salary
<chr> <int> <dbl> <chr> <dbl> <dbl> <dbl>
1 Back end D… 242 33 Female 2 5 110000
2 Back end D… 242 32 Male 1 4 95000
3 Back end D… 242 26 Female 2 3 90000
4 Back end D… 242 26 Female 2 2 70000
5 Back end D… 242 24 Female 1 1 60000
6 Back end D… 242 26 Female 2 3 90000
7 Back end D… 242 24 Female 2 1 60000
8 Back end D… 242 34 Male 2 6 125000
9 Back end D… 242 29 Female 1 3 85000
10 Back end D… 242 23 Male 1 1 55000
# ℹ 6,388 more rows
# ℹ 4 more variables: Country <chr>, Race <chr>, Senior <dbl>, SalaryKat <fct>
Back end Developer : 242
Content Marketing Manager : 73
Data Analyst : 391
Data Scientist : 515
Digital Marketing Manager : 52
Director of Data Science : 57
Director of HR : 69
Director of Marketing : 88
Financial Analyst : 53
Financial Manager : 139
Front end Developer : 239
Front End Developer : 31
Full Stack Engineer : 304
HR Generalist : 104
Human Resources Coordinator : 50
Human Resources Manager : 152
Marketing Analyst : 144
Marketing Coordinator : 167
Marketing Director : 65
Marketing Manager : 315
Operations Manager : 122
Product Designer : 80
Product Manager : 323
Product Marketing Manager : 70
Project Engineer : 317
Project Manager : 34
Receptionist : 57
Research Director : 75
Research Scientist : 119
Sales Associate : 212
Sales Director : 62
Sales Executive : 38
Sales Manager : 58
Sales Representative : 81
Software Developer : 186
Software Engineer : 809
Software Engineer Manager : 376
Web Developer : 129
Job Typen
Anzahl der technischen und adminsitrativen Berufe
Code
# Filtern nach technischen Jobstechnische_jobs <- filtered_data[grep("data|engineer|developer|analyst|scientist", tolower(filtered_data$Job.Title)), ]# Filtern nach wirtschaftlichen/administrativen Jobsadmin_jobs <- filtered_data[grep("associate|director|manager|sales|coordinator|generalist|receptionist|designer", tolower(filtered_data$Job.Title)), ]# Beispiel für die Ausgabe der ersten paar Zeilen der gefilterten Datenhead(technische_jobs)
# A tibble: 6 × 11
Job.Title job_count Age Gender Education.Level Years.Of.Experience Salary
<chr> <int> <dbl> <chr> <dbl> <dbl> <dbl>
1 Back end De… 242 33 Female 2 5 110000
2 Back end De… 242 32 Male 1 4 95000
3 Back end De… 242 26 Female 2 3 90000
4 Back end De… 242 26 Female 2 2 70000
5 Back end De… 242 24 Female 1 1 60000
6 Back end De… 242 26 Female 2 3 90000
# ℹ 4 more variables: Country <chr>, Race <chr>, Senior <dbl>, SalaryKat <fct>
# Anzahl der technischen Jobsanzahl_technische_jobs <-nrow(technische_jobs)cat("Anzahl der technischen Jobs:", anzahl_technische_jobs, "\n")
Anzahl der technischen Jobs: 3912
Code
# Anzahl der administrativen Jobsanzahl_admin_jobs <-nrow(admin_jobs)cat("Anzahl der administrativen Jobs:", anzahl_admin_jobs, "\n")
Anzahl der administrativen Jobs: 2919
Code
# Anzahl der Zeilen (Werte) in filtered_dataanzahl_werte_filtered_data <-nrow(filtered_data)# Anzeigen der Anzahl der Wertecat("Anzahl der Werte in filtered_data:", anzahl_werte_filtered_data, "\n")
problem da jobs anscheinend doppelt gezählt werden ich glaube wir müssen den jobs eine id geben
Code
# Add ID-Spaltefiltered_data$ID <-1:nrow(filtered_data)# Filtern nach technischen Jobs und Entfernen von Duplikatentechnische_jobs2 <-unique(filtered_data[grep("data|engineer|developer|analyst|scientist", tolower(filtered_data$Job.Title)), ])# Filtern nach wirtschaftlichen/administrativen Jobs und Entfernen von Duplikatenadmin_jobs2 <-unique(filtered_data[grep("associate|director|manager|sales|coordinator|generalist|receptionist|designer", tolower(filtered_data$Job.Title)), ])# Merke die IDs der übereinstimmenden Zeilenids_technische_jobs <- filtered_data$ID[filtered_data$Job.Title %in% technische_jobs2$Job.Title]ids_admin_jobs <- filtered_data$ID[filtered_data$Job.Title %in% admin_jobs2$Job.Title]# Entferne die entsprechenden Zeilen aus filtered_datafiltered_data_neu <- filtered_data[!(filtered_data$ID %in%c(ids_technische_jobs, ids_admin_jobs)), ]# Beispiel für die Ausgabe der ersten paar Zeilen der gefilterten Datenhead(filtered_data_neu)
# A tibble: 0 × 12
# ℹ 12 variables: Job.Title <chr>, job_count <int>, Age <dbl>, Gender <chr>,
# Education.Level <dbl>, Years.Of.Experience <dbl>, Salary <dbl>,
# Country <chr>, Race <chr>, Senior <dbl>, SalaryKat <fct>, ID <int>
Code
anzahl_technische_jobs2 <-nrow(technische_jobs2)cat("Anzahl der technischen Jobs2:", anzahl_technische_jobs2, "\n")
Anzahl der technischen Jobs2: 3912
Code
anzahl_admin_jobs2 <-nrow(admin_jobs2)cat("Anzahl der administrativen Jobs2:", anzahl_admin_jobs2, "\n")
Anzahl der administrativen Jobs2: 2919
basieren auf filtered_data ein neues dataset erstellt wird aus dem ein datensatz gelöscht wird sobald eine zeile einer der _jobs table zugewiesen wird damit es nicht doppelt gezählt werden kann. Warum auch immer funktioniert das nicht also neuer lösungsansatz:
Das Problem mit der Klassifizierung der Jobs nach Technisch und Administrativ lässt sich lösen in dem ich die nicht in 2 tabellen aufteile sondern jeder Zeile einen Wert des Entsprechenden job types zuordne
Code
# Erstellung der neuen Spalte "job_type" basierend auf den gegebenen Filternfiltered_data$job_type <-ifelse(grepl("data|engineer|developer|analyst|scientist", tolower(filtered_data$Job.Title)),0, # 0 für technische Jobsifelse(grepl("associate|director|manager|sales|coordinator|generalist", tolower(filtered_data$Job.Title)),1, # 1 für administrative JobsNA# NA für alle anderen ))# Anzeige der Anzahl aller Zeilen im Datensatz und der Anzahl der Zeilen für jede job_type-Ausprägungtotal_rows <-nrow(filtered_data)count_job_types <-table(filtered_data$job_type, useNA ="ifany")# Ausgabe der Ergebnisseprint(paste("Gesamtanzahl der Zeilen im Datensatz:", total_rows))
[1] "Gesamtanzahl der Zeilen im Datensatz: 6398"
Code
print("Anzahl der Zeilen für jede job_type-Ausprägung:")
[1] "Anzahl der Zeilen für jede job_type-Ausprägung:"
Code
print(count_job_types)
0 1 <NA>
3912 2349 137
Auflösen der NAs
Code
# Auswahl aller Zeilen mit NA-Werten in der Spalte "job_type"na_job_type_rows <-subset(filtered_data, is.na(job_type))# Anzeige der ausgewählten Zeilen mit NA in "job_type"na_job_type_rows
Das Ergebnis ist eine Table welche nur aus Product Designer & Receptionist besteht. Diese fügen wir den Administrativen Jobs hinzu.
Code
# Aktualisierung der job_type-Spalte für die spezifischen Job-Titelfiltered_data$job_type[filtered_data$Job.Title %in%c("Product Designer", "Receptionist")] <-1# Anzeige der aktualisierten Daten für die ausgewählten Job-Titelsubset(filtered_data, Job.Title %in%c("Product Designer", "Receptionist"))
# Anzeige der Anzahl aller Zeilen im Datensatz und der Anzahl der Zeilen für jede job_type-Ausprägungtotal_rows <-nrow(filtered_data)count_job_types <-table(filtered_data$job_type, useNA ="ifany")# Ausgabe der Ergebnisseprint(paste("Gesamtanzahl der Zeilen im Datensatz:", total_rows))
[1] "Gesamtanzahl der Zeilen im Datensatz: 6398"
Code
print("Anzahl der Zeilen für jede job_type-Ausprägung:")
[1] "Anzahl der Zeilen für jede job_type-Ausprägung:"
Code
print(count_job_types)
0 1
3912 2486
Done. Im folgenden werden alle Diagramme auch über job_type ausgewertet könnnen.
Expats & Einheimische
Code
ggplot(filtered_data, aes(x =factor(Gender), y = Years.Of.Experience, fill = Gender)) +geom_boxplot(alpha =0.7) +labs(title ="Boxplot: Years of Experience vs. Gender",x ="Gender",y ="Years of Experience",fill ="Gender") +theme_minimal()
Code
# Bibliothek ggplot2 ladenlibrary(ggplot2)# Daten für China filterndata_china <-subset(filtered_data, Country =="China")# Boxplot erstellenggplot(data_china, aes(x =factor(Gender), y = Years.Of.Experience, fill = Gender)) +geom_boxplot(alpha =0.7) +labs(title ="Boxplot: Years of Experience vs. Gender (China)",x ="Gender",y ="Years of Experience",fill ="Gender") +theme_minimal()
Code
# Bibliothek ggplot2 ladenlibrary(ggplot2)# Daten für China filterndata_china <-subset(filtered_data, Country =="China")# Boxplot für Salary vs. Gender erstellenggplot(data_china, aes(x =factor(Gender), y = Salary, fill = Gender)) +geom_boxplot(alpha =0.7) +labs(title ="Boxplot: Salary vs. Gender (China)",x ="Gender",y ="Salary",fill ="Gender") +theme_minimal()
Code
# Bibliothek ggplot2 ladenlibrary(ggplot2)# Daten für USA filterndata_usa <-subset(filtered_data, Country =="USA")# Boxplot erstellenggplot(data_usa, aes(x =factor(Gender), y = Years.Of.Experience, fill = Gender)) +geom_boxplot(alpha =0.7) +labs(title ="Boxplot: Years of Experience vs. Gender (USA)",x ="Gender",y ="Years of Experience",fill ="Gender") +theme_minimal()
Code
# Bibliothek ggplot2 ladenlibrary(ggplot2)# Daten für USA filterndata_usa <-subset(filtered_data, Country =="USA")# Boxplot für Salary vs. Gender erstellenggplot(data_usa, aes(x =factor(Gender), y = Salary, fill = Gender)) +geom_boxplot(alpha =0.7) +labs(title ="Boxplot: Salary vs. Gender (USA)",x ="Gender",y ="Salary",fill ="Gender") +theme_minimal()
ist jetzt der gender pay gap in china doch größer da der größte faktor für salary years of experience ist?
Code
# Korrelation zwischen Salary und Years.Of.Experience berechnencorrelation_salary_experience <-cor(filtered_data$Salary, filtered_data$Years.Of.Experience)# Ausgabe des Ergebnissescat("Die Korrelation zwischen Salary und Years.Of.Experience ist:", correlation_salary_experience, "\n")
Die Korrelation zwischen Salary und Years.Of.Experience ist: 0.8103542
Code
# Korrelation zwischen Salary und Education.Level berechnencorrelation_salary_education <-cor(filtered_data$Salary, filtered_data$Education.Level, use ="complete.obs")# Ausgabe des Ergebnissescat("Die Korrelation zwischen Salary und Education.Level ist:", correlation_salary_education, "\n")
Die Korrelation zwischen Salary und Education.Level ist: 0.6374551
Code
# Korrelation zwischen Salary und Age berechnencorrelation_salary_age <-cor(filtered_data$Salary, filtered_data$Age, use ="complete.obs")# Ausgabe des Ergebnissescat("Die Korrelation zwischen Salary und Age ist:", correlation_salary_age, "\n")
Die Korrelation zwischen Salary und Age ist: 0.7291603
Code
# Korrelation zwischen Years.Of.Experience und Age berechnencorrelation_experience_age <-cor(filtered_data$Years.Of.Experience, filtered_data$Age, use ="complete.obs")# Ausgabe des Ergebnissescat("Die Korrelation zwischen Years.Of.Experience und Age ist:", correlation_experience_age, "\n")
Die Korrelation zwischen Years.Of.Experience und Age ist: 0.9363709
Code
# Annahme: "filtered_data" ist Ihr Datensatz# Annahme: Die Spalten sind "Seniority" und "Years.Of.Experience"# Korrelation zwischen Seniority und Years.Of.Experience berechnencorrelation_seniority_experience <-cor(filtered_data$Senior, filtered_data$Years.Of.Experience, use ="complete.obs")# Ausgabe des Ergebnissescat("Die Korrelation zwischen Seniority und Years.Of.Experience ist:", correlation_seniority_experience, "\n")
Die Korrelation zwischen Seniority und Years.Of.Experience ist: 0.3192657
das ergebnis der correlationen: von salary und years.of.experience ist es 0.81 von Salary und Age ist es 0.73 und die von Age und Years.Of.Experience ist 0.93 wie kommt so ein starker unterschied zu stande bei den werten im vergleich zu salary obwohl sie doch eine hohe correlation zueinander haben
Verteilung der Daten: Es ist möglich, dass die Verteilung der Daten in den Variablen “Age” und “Years.Of.Experience” anders ist als in der Variable “Salary”. Wenn die Daten in “Age” und “Years.Of.Experience” breiter gestreut sind, kann dies zu einer geringeren Korrelation führen, selbst wenn eine starke lineare Beziehung besteht.
Nicht-lineare Beziehung: Die Korrelation misst nur lineare Beziehungen. Wenn die Beziehung zwischen “Age” und “Years.Of.Experience” nicht linear ist, könnte dies zu einem niedrigeren Korrelationswert führen.
Ausreißer: Das Vorhandensein von Ausreißern kann die Korrelation beeinflussen. Wenn es Ausreißer in einer der Variablen gibt, kann dies den Korrelationswert beeinträchtigen.
Stichprobengröße: Bei kleineren Stichproben können Korrelationswerte instabiler sein.
# Durchschnittliche Gehälter pro Jobtyp für technische_jobs2 berechnen
ggplot(all_average_salaries, aes(x = Job.Type, y = Average.Salary, fill = Job.Type)) +
geom_bar(stat = “identity”, position = “dodge”, alpha = 0.7) +
labs(title = “Durchschnittliche Gehälter nach Jobtyp”,
x = “Jobtyp”,
y = “Durchschnittliches Gehalt”) +
theme_minimal()
Code
# Filtern der Daten für technische und administrative Jobs basierend auf den Kriterientechnische_jobs <-subset(filtered_data, job_type ==0)admin_jobs <-subset(filtered_data, job_type ==1)# Durchschnittliche Gehälter pro Jobtyp für technische Jobs berechnenaverage_salaries_technical <-mean(technische_jobs$Salary, na.rm =TRUE)# Durchschnittliche Gehälter pro Jobtyp für administrative Jobs berechnenaverage_salaries_admin <-mean(admin_jobs$Salary, na.rm =TRUE)# Zusammenführen der durchschnittlichen Gehälter in einem Datenrahmenall_average_salaries <-data.frame(Job.Type =c("technisch", "admin"),Average.Salary =c(average_salaries_technical, average_salaries_admin))# Erstellung des Diagramms mit angepasster Achsenbeschriftungggplot(all_average_salaries, aes(x = Job.Type, y = Average.Salary, fill = Job.Type)) +geom_bar(stat ="identity", position ="dodge", alpha =0.7) +labs(title ="Durchschnittliche Gehälter nach Jobtyp",x ="Jobtyp",y ="Durchschnittliches Gehalt") +theme_minimal() +scale_y_continuous(labels = scales::comma) # Verwendung von scales::comma für die Achsenbeschriftung in Tausenden
Und das Obwohl in den Admin Jobs auch direktoren und Manager vertreten sind
Nehmen wir an das Manager ein Job Titel wie Projekt Manager ist und nicht Manager für Projekt Management und dieser Titel in unserem Datensatz Director ist? Thema Führungsposition
Datenaufbereitung 2
Unsere Untersuchungen haben Ergeben das wir die Daten für unsere Explorative Datenanalyse aber auch die Regression neu aufbereiten müssen.
Dazu suchen wir: unterscheide ich einen native und expat im jeweiligen Land. Welche annahmen sind dafür nötig? Hier die annahme das White generell nicht ausgewandert ist da wir hier länder mit ähnlicher kultur und salary haben
Code
ggplot(filtered_data, aes(x = Country, fill = Race)) +geom_bar(position ="dodge") +labs(title ="Count of Races in Each Country",x ="Country",y ="Count") +theme(axis.text.x =element_text(angle =45, hjust =1))
Dafür füge ich eine neue spalte ein die mit numerishcen werten arbeitet. 0 steht für einheimischer und 1 für expat. Den wert null erhalten alle zeilen bei denen wir folgende übereinstimmung feststllen (land und ethnizität hier country und race): African American (USA) White (Canada, USA, UK, Australia) Chinese (China) Australian(Australia) Welsh (UK) jede andere race ist ja dementsprechend expat und erhält eine 1 in der spalte expat
Code
# Erstellen der Spalte "Expat" basierend auf den angegebenen Kriterienfiltered_data$Expat <-0# Standardwert 0 (Einheimische)# Festlegen von Bedingungen für Expats basierend auf Land und Ethnizitätexpat_conditions <-list( filtered_data$Race =="African American"& filtered_data$Country =="USA", filtered_data$Race %in%c("White", "Chinese", "Australian", "Welsh") & filtered_data$Country %in%c("Canada", "USA", "UK", "Australia"),TRUE# Für alle anderen Rassen (Expat))# Setzen von Werten entsprechend den Bedingungenfiltered_data$Expat <-ifelse(expat_conditions[[1]] | expat_conditions[[2]], 0, ifelse(expat_conditions[[3]], 1, NA))# Anzeige des aktualisierten Datensatzes zur Überprüfunghead(filtered_data)
# A tibble: 6 × 14
Job.Title job_count Age Gender Education.Level Years.Of.Experience Salary
<chr> <int> <dbl> <chr> <dbl> <dbl> <dbl>
1 Back end De… 242 33 Female 2 5 110000
2 Back end De… 242 32 Male 1 4 95000
3 Back end De… 242 26 Female 2 3 90000
4 Back end De… 242 26 Female 2 2 70000
5 Back end De… 242 24 Female 1 1 60000
6 Back end De… 242 26 Female 2 3 90000
# ℹ 7 more variables: Country <chr>, Race <chr>, Senior <dbl>, SalaryKat <fct>,
# ID <int>, job_type <dbl>, Expat <dbl>
Thesen
Genderpaygap
Männer verdienen mehr als Frauen
Die Differenz der Salary zwischen den Geschlechtern ist in China höher als in den westlichen Ländern.
Männer haben im Durchschnitt mehr Yrs of Experience als Frauen -> Lässt sich die Genderpaygap auf die Yrs of Exp übertragen? Und gilt dies auch für China
1.: Männer verdienen mehr als Frauen
Code
ggplot(filtered_data, aes(x =factor(Gender), y = Salary, fill = Gender)) +geom_boxplot(alpha =0.7) +labs(title ="Boxplot: Salary vs. Gender",x ="Gender",y ="Salary",fill ="Gender") +theme_minimal()
These Korrekt
2.: Die Differenz der Salary zwischen den Geschlechtern ist in China höher als in den westlichen Ländern. Hier alle westlichen Länder hinzufügen
Code
# Daten für USA filterndata_usa <-subset(filtered_data, Country =="USA")# Boxplot erstellenggplot(data_usa, aes(x =factor(Gender), y = Years.Of.Experience, fill = Gender)) +geom_boxplot(alpha =0.7) +labs(title ="Boxplot: Years of Experience vs. Gender (USA)",x ="Gender",y ="Years of Experience",fill ="Gender") +theme_minimal()
Code
# Daten für China filterndata_china <-subset(filtered_data, Country =="China")# Boxplot für Salary vs. Gender erstellenggplot(data_china, aes(x =factor(Gender), y = Salary, fill = Gender)) +geom_boxplot(alpha =0.7) +labs(title ="Boxplot: Salary vs. Gender (China)",x ="Gender",y ="Salary",fill ="Gender") +theme_minimal()
These Korrekt
3.: Männer haben im Durchschnitt mehr Yrs of Experience als Frauen -> Lässt sich die Genderpaygap auf die Yrs of Exp übertragen? Und gilt dies auch für China
Code
ggplot(filtered_data, aes(x =factor(Gender), y = Years.Of.Experience, fill = Gender)) +geom_boxplot(alpha =0.7) +labs(title ="Boxplot: Years of Experience vs. Gender",x ="Gender",y ="Years of Experience",fill ="Gender") +theme_minimal()
Code
# Daten für China filterndata_china <-subset(filtered_data, Country =="China")# Boxplot erstellenggplot(data_china, aes(x =factor(Gender), y = Years.Of.Experience, fill = Gender)) +geom_boxplot(alpha =0.7) +labs(title ="Boxplot: Years of Experience vs. Gender (China)",x ="Gender",y ="Years of Experience",fill ="Gender") +theme_minimal()
Code
# Daten für USA filterndata_usa <-subset(filtered_data, Country =="USA")# Boxplot erstellenggplot(data_usa, aes(x =factor(Gender), y = Years.Of.Experience, fill = Gender)) +geom_boxplot(alpha =0.7) +labs(title ="Boxplot: Years of Experience vs. Gender (USA)",x ="Gender",y ="Years of Experience",fill ="Gender") +theme_minimal()
ist jetzt der gender pay gap in china doch größer da der größte faktor für salary years of experience ist?
Dafür schauen wir uns an: Korrelation von years of experience und salary
Code
# Korrelation zwischen Salary und Years.Of.Experience berechnencorrelation_salary_experience <-cor(filtered_data$Salary, filtered_data$Years.Of.Experience)# Ausgabe des Ergebnissescat("Die Korrelation zwischen Salary und Years.Of.Experience ist:", correlation_salary_experience, "\n")
Die Korrelation zwischen Salary und Years.Of.Experience ist: 0.8103542
These Korrekt da es im gleichen Verhältnis steht. Nicht desto trotz gibt es einen Unterschied zwischen den Geschlechtern bei gleichbleibender Arbeitderfahrung was auf einen kleinen Gender Pay gap schließen lässt.
Expats verdienen mehr als Einheimisch
Unsere Untersuchungen haben Ergeben das wir die Daten für unsere Explorative Datenanalyse aber auch die Regression neu aufbereiten müssen.
Dazu suchen wir: unterscheide ich einen native und expat im jeweiligen Land. Welche annahmen sind dafür nötig? Hier die annahme das White generell nicht ausgewandert ist da wir hier länder mit ähnlicher kultur und salary haben
1.: Alle Ethnizitäten je Land
Code
ggplot(filtered_data, aes(x = Country, fill = Race)) +geom_bar(position ="dodge") +labs(title ="Count of Races in Each Country",x ="Country",y ="Count") +theme(axis.text.x =element_text(angle =45, hjust =1))
Daten für Analyse von Expats und Einheimischen bereits Aufbereitet. Bitte hier nochmal beschrieben
Code
# Erstellung des Boxplots für Expats und Einheimischeggplot(filtered_data, aes(x =as.factor(Expat), y = Salary, fill =factor(Expat))) +geom_boxplot() +labs(title ="Vergleich der Gehälter von Expats und Einheimischen",x ="Expat",y ="Gehalt") +scale_x_discrete(labels =c("Einheimische (0)", "Expats (1)")) +theme_minimal()
Code
# Mittelwert der Gehälter für Expats (Expat = 1)mean_salary_expat <-mean(filtered_data$Salary[filtered_data$Expat ==1], na.rm =TRUE)mean_salary_expat
[1] 116928.1
Code
# Mittelwert der Gehälter für Einheimische (Expat = 0)mean_salary_native <-mean(filtered_data$Salary[filtered_data$Expat ==0], na.rm =TRUE)mean_salary_native
[1] 116572.5
These verworfen. Da es offensichtlich keine Unterschiede gibt. Ggf. noch einzelne Ethnizitäten betrachten
Gehaltscap education level vorhanden?
Ohne ein Mindestmaß ein Bildung ist keine weitere Gehaltsentwicklung möglich
Bildungsniveau Codes:
0 = High School Abschluss
1 = Bachelor
2 = Master
3 = Doctor
Deskriptive Statistiken: Man könnte Quantile oder Perzentile des Gehalts für jedes Bildungsniveau berechnen. Dies bietet einen Überblick über die Verteilung der Gehälter und zeigt potenzielle Grenzwerte auf.
Boxplots pro Bildungsniveau: Man könnte Boxplots für jedes Bildungsniveau erstellen, um die Verteilung der Gehälter visuell zu vergleichen. Dies kann helfen, Ausreißer und Unterschiede zwischen den Bildungsniveaus zu identifizieren.
Visualisierungen: Verschiedene Visualisierungen wie Scatterplots oder Liniendiagramme könnten erstellt werden, um Trends oder Muster zwischen Gehalt und Bildungsniveau zu erkennen.
1.: Desktiptive Statistiken:
Code
# Bibliotheken ladenlibrary(ggplot2)library(dplyr)# Daten berechnensalary_percentiles <- filtered_data %>%group_by(Education.Level) %>%summarise(`10th Percentile`=quantile(Salary, probs =0.1, na.rm =TRUE),`25th Percentile`=quantile(Salary, probs =0.25, na.rm =TRUE),`50th Percentile (Median)`=quantile(Salary, probs =0.5, na.rm =TRUE),`75th Percentile`=quantile(Salary, probs =0.75, na.rm =TRUE),`90th Percentile`=quantile(Salary, probs =0.9, na.rm =TRUE))# Reshape der Daten für das Plottingsalary_percentiles_long <- salary_percentiles %>% tidyr::pivot_longer(cols =-Education.Level, names_to ="Percentile", values_to ="Salary")# Diagramm erstellenggplot(salary_percentiles_long, aes(x = Education.Level, y = Salary, fill = Percentile)) +geom_bar(stat ="identity", position ="dodge", alpha =0.7) +labs(title ="Perzentile des Gehalts nach Bildungsniveau",x ="Bildungsniveau",y ="Gehalt",fill ="Perzentil") +theme_minimal()
Code
# Berechnung der Durchschnittsgehälter pro Bildungsniveauaverage_salary_education <-aggregate(Salary ~ Education.Level, data = filtered_data, FUN = mean, na.rm =TRUE)# Anzeige der Durchschnittsgehälter pro Bildungsniveauaverage_salary_education
# Bildungsniveau nach aufsteigender Reihenfolge sortierenfiltered_data <- filtered_data %>%mutate(Education.Level =factor(Education.Level, levels =unique(sort(Education.Level))))# Boxplot erstellenggplot(filtered_data, aes(x =reorder(factor(Education.Level), Salary, FUN = median), y = Salary)) +geom_boxplot(fill ="lightblue", color ="black") +labs(title ="Boxplot des Gehalts nach Bildungsniveau",x ="Bildungsniveau",y ="Gehalt") +theme_minimal()
3.: Visualisierungen:
Code
# Bildungsniveau nach aufsteigender Reihenfolge sortierenfiltered_data <- filtered_data %>%mutate(Education.Level =factor(Education.Level, levels =unique(sort(Education.Level))))# Scatterplot erstellenggplot(filtered_data, aes(x =reorder(factor(Education.Level), Salary, FUN = median), y = Salary)) +geom_point() +labs(title ="Gehalt nach Bildungslevel",x ="Bildungslevel",y ="Gehalt") +theme_minimal()
Code
# Bildungslevel neu ordnenfiltered_data$Education.Level <-factor(filtered_data$Education.Level, levels =c("0", "1", "2", "3"))# Liniendiagramm mit umgekehrter Reihenfolge des Bildungsniveaus erstellenggplot(filtered_data, aes(x = Education.Level, y = Salary, group =1)) +geom_line() +stat_summary(fun.y = median, geom ="point", size =3, color ="red") +labs(title ="Gehalt nach Bildungslevel",x ="Bildungslevel",y ="Gehalt") +theme_minimal()
Warning: The `fun.y` argument of `stat_summary()` is deprecated as of ggplot2 3.3.0.
ℹ Please use the `fun` argument instead.
These Korrekt: Ohne einen Hochschulabschluss gibt es eine Gehaltsgrenze. Die top 90% ohne Hochschulabschluss fangen bei den unteren 10% mit Hochschulabschluss an aus der Sicht des Gehalts.
Technische Jobs haben ein höheres Gehalt als Administrative Jobs - jedes Land?
1.: Daten Aufbereiten
Daten Aufbereiten
2.: Insgesamt
Code
# Filtern der Daten für technische und administrative Jobs basierend auf den Kriterientechnische_jobs <-subset(filtered_data, job_type ==0)admin_jobs <-subset(filtered_data, job_type ==1)# Durchschnittliche Gehälter pro Jobtyp für technische Jobs berechnenaverage_salaries_technical <-mean(technische_jobs$Salary, na.rm =TRUE)# Durchschnittliche Gehälter pro Jobtyp für administrative Jobs berechnenaverage_salaries_admin <-mean(admin_jobs$Salary, na.rm =TRUE)# Zusammenführen der durchschnittlichen Gehälter in einem Datenrahmenall_average_salaries <-data.frame(Job.Type =c("technisch", "admin"),Average.Salary =c(average_salaries_technical, average_salaries_admin))# Erstellung des Diagramms mit angepasster Achsenbeschriftungggplot(all_average_salaries, aes(x = Job.Type, y = Average.Salary, fill = Job.Type)) +geom_bar(stat ="identity", position ="dodge", alpha =0.7) +labs(title ="Durchschnittliche Gehälter nach Jobtyp",x ="Jobtyp",y ="Durchschnittliches Gehalt") +theme_minimal() +scale_y_continuous(labels = scales::comma) # Verwendung von scales::comma für die Achsenbeschriftung in Tausenden
3.: Je Land
vergleich nach ländern
These Korrekt Und das Obwohl in den Admin Jobs auch direktoren und Manager vertreten sind
Nehmen wir an das Manager ein Job Titel wie Projekt Manager ist und nicht Manager für Projekt Management und dieser Titel in unserem Datensatz Director ist? Thema Führungsposition